package org.cocopapaya.springws.ext.xml;

import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.util.Assert;
import org.springframework.xml.JaxpVersion;
import org.springframework.xml.validation.XmlValidationException;
import org.springframework.xml.validation.XmlValidator;
import org.springframework.xml.validation.XmlValidatorFactory;


public class CustomXmlValidatorFactory {
	
	   private static final Log logger = LogFactory.getLog(XmlValidatorFactory.class);

	    /** Constant that defines a W3C XML Schema. */
	    public static final String SCHEMA_W3C_XML = "http://www.w3.org/2001/XMLSchema";

	    /** Constant that defines a RELAX NG Schema. */
	    public static final String SCHEMA_RELAX_NG = "http://relaxng.org/ns/structure/1.0";

	    /**
	     * Create a {@link XmlValidator} with the given schema resource and schema language type. The schema language must
	     * be one of the <code>SCHEMA_XXX</code> constants.
	     *
	     * @param schemaResource a resource that locates the schema to validate against
	     * @param schemaLanguage the language of the schema
	     * @return a validator
	     * @throws IOException              if the schema resource cannot be read
	     * @throws IllegalArgumentException if the schema language is not supported
	     * @throws IllegalStateException    if JAXP 1.0 cannot be located
	     * @throws XmlValidationException   if a <code>XmlValidator</code> cannot be created
	     * @see #SCHEMA_RELAX_NG
	     * @see #SCHEMA_W3C_XML
	     */
	    public static XmlValidator createValidator(Resource schemaResource, String schemaLanguage) throws IOException {
	        return createValidator(new Resource[]{schemaResource}, schemaLanguage);
	    }

	    /**
	     * Create a {@link XmlValidator} with the given schema resources and schema language type. The schema language must
	     * be one of the <code>SCHEMA_XXX</code> constants.
	     *
	     * @param schemaResources an array of resource that locate the schemas to validate against
	     * @param schemaLanguage  the language of the schemas
	     * @return a validator
	     * @throws IOException              if the schema resource cannot be read
	     * @throws IllegalArgumentException if the schema language is not supported
	     * @throws IllegalStateException    if JAXP 1.0 cannot be located
	     * @throws XmlValidationException   if a <code>XmlValidator</code> cannot be created
	     * @see #SCHEMA_RELAX_NG
	     * @see #SCHEMA_W3C_XML
	     */
	    public static XmlValidator createValidator(Resource[] schemaResources, String schemaLanguage) throws IOException {
	        Assert.notEmpty(schemaResources, "No resources given");
	        Assert.hasLength(schemaLanguage, "No schema language provided");
	        Assert.isTrue(SCHEMA_W3C_XML.equals(schemaLanguage) || SCHEMA_RELAX_NG.equals(schemaLanguage),
	                "Invalid schema language: " + schemaLanguage);
	        for (Resource schemaResource : schemaResources) {
	            Assert.isTrue(schemaResource.exists(), "schema [" + schemaResource + "] does not exist");
	        }
	        if (JaxpVersion.getJaxpVersion() >= JaxpVersion.JAXP_13) {
	            logger.trace("Creating JAXP 1.3 XmlValidator");
	            return JaxpValidatorFactory.createValidator(schemaResources, schemaLanguage);
	        }
	        else {
	            throw new IllegalStateException("Could not locate JAXP 1.3.");
	        }
	    }

}
